﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using PairingMatrix.Common.Command;
using PairingMatrix.Common.Enum;
using PairingMatrix.Model;
using System.Linq;

namespace PairingMatrix.ViewModel
{
    public class CardWallViewModel : ViewModelBase, ICardWallViewModel
    {
        private readonly CardWallModel _model;
        private AbsenteesViewModel absenteesViewModel;

        public CardWallViewModel(CardWallModel model)
        {
            _model = model;
            _model.PropertyChanged += ModelPropertyChanged;
            
            TeamMembers = new ObservableCollection<ITeamMemberCardViewModel>();
            _model.TeamMembers.ToList().ForEach(t => TeamMembers.Add(new TeamMemberCardViewModel(t)));

            ProjectCards = new ObservableCollection<IProjectCardViewModel>();
            _model.ProjectCards.ToList().ForEach(p => ProjectCards.Add(new ProjectCardViewModel(p)));

            MingleCards = new ObservableCollection<IProjectCardViewModel>();

            StartDateStrip = new DateStripViewModel(DateTime.Now);
            EndDateStrip = new DateStripViewModel(DateTime.Now);
            EndDateStrip.DateSelected += EndDateStrip_DateSelected;

            _model.ProjectCards.CollectionChanged += ProjectCards_CollectionChanged;
            _model.MingleCards.CollectionChanged += MingleCards_CollectionChanged;
            _model.TeamMembers.CollectionChanged += TeamMembers_CollectionChanged;
            absenteesViewModel = new AbsenteesViewModel(_model.Absentees, TeamMembers);

            SettingsViewModel = new SettingsViewModel(_model.Settings);
            _timerViewModel = new TimerViewModel(_model);

            ReadyForDevPriorityCounter = new PriorityCounterViewModel(_model.ProjectCards, new List<StoryStatus> { StoryStatus.New, StoryStatus.Triage, StoryStatus.InPlanning, StoryStatus.ReadyForAnalysis, StoryStatus.InAnalysis, StoryStatus.ReadyForDev, StoryStatus.OnHold, StoryStatus.Split });
            InDevPriorityCounter = new PriorityCounterViewModel(_model.ProjectCards, new List<StoryStatus> { StoryStatus.InDev, StoryStatus.InDevWaitingforBuild, StoryStatus.ReadyForBAAcceptance });
            InQAPriorityCounter = new PriorityCounterViewModel(_model.ProjectCards, new List<StoryStatus> { StoryStatus.ReadyForQA, StoryStatus.InQA, StoryStatus.ReadyForShowcase, StoryStatus.ReadyForVerification, StoryStatus.AwaitingFix, StoryStatus.AwaitingReTestbyQA, StoryStatus.AwaitingReTestbyCustomer });
            ShowcaseDonePriorityCounter = new PriorityCounterViewModel(_model.ProjectCards, new List<StoryStatus> { StoryStatus.ReadyForRegressionTesting, StoryStatus.InRegressionTesting, StoryStatus.ReadyForSAT, StoryStatus.InSAT});
            ClosedPriorityCounter = new PriorityCounterViewModel(_model.ProjectCards, new List<StoryStatus> { StoryStatus.Closed, StoryStatus.Deleted, StoryStatus.Quarantine });
        }

        
        static double mingleReadyForDevX = 0;
        static double mingleReadyForDevY = 0;
        static double mingleInDevX = 550;
        static double mingleInDevY = 0;
        static double mingleInQAX = 1100;
        static double mingleInQAY = 0;
        static double mingleShowCaseCompleteX = 1650;
        static double mingleShowCaseCompleteY = 0;
        static double mingleClosedX = 2200;
        static double mingleClosedY = 0;

        void MingleCards_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                var projectCardModel = (ProjectCardModel)e.NewItems[0];
                
                if(ProjectCards.Any(p => p.CardNumber == projectCardModel.CardNumber))
                    return;

                var currentMingleXYAllowed = GetCurrentXYAllowedForThisStatus(projectCardModel);

                var projectCardViewModel = new MingleCardViewModel(projectCardModel) { Position = new Point(currentMingleXYAllowed[0] + 70, currentMingleXYAllowed[1] + 120) };
                MingleCards.Add(projectCardViewModel);

                if (currentMingleXYAllowed[0] >= currentMingleXYAllowed[2])
                {
                    currentMingleXYAllowed[0] = currentMingleXYAllowed[2] - 300;
                    currentMingleXYAllowed[1] += 120;
                }
                else
                {
                    currentMingleXYAllowed[0] += 150;
                }

                if (currentMingleXYAllowed[1] >= 840)
                {
                    currentMingleXYAllowed[1] = 0;
                }


                SetCurrentXYAllowedForThisStatus(projectCardModel, currentMingleXYAllowed);


            }
            else if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                MingleCards.Clear();
                mingleReadyForDevX = 0;
                mingleReadyForDevY = 0;
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                var projectCardModel = (ProjectCardModel)e.OldItems[0];
                MingleCards.Remove(ProjectCards.First(c => c.CardNumber == projectCardModel.CardNumber));
            }
        }

        private void SetCurrentXYAllowedForThisStatus(ProjectCardModel projectCardModel, List<double> currentMingleXyAllowed)
        {
            switch (projectCardModel.DevStage)
            {
                case StoryStatus.New:
                case StoryStatus.Triage:
                case StoryStatus.InPlanning:
                case StoryStatus.ReadyForAnalysis:
                case StoryStatus.InAnalysis:
                case StoryStatus.ReadyForDev:
                case StoryStatus.OnHold:
                case StoryStatus.Split:
                    mingleReadyForDevX = currentMingleXyAllowed[0];
                    mingleReadyForDevY = currentMingleXyAllowed[1];
                    break;
                case StoryStatus.InDev:
                case StoryStatus.InDevWaitingforBuild:
                case StoryStatus.ReadyForBAAcceptance:
                    mingleInDevX = currentMingleXyAllowed[0];
                    mingleInDevY = currentMingleXyAllowed[1];
                    break;
                case StoryStatus.ReadyForQA:
                case StoryStatus.InQA:
                case StoryStatus.ReadyForShowcase:
                case StoryStatus.ReadyForVerification:
                case StoryStatus.AwaitingFix:
                case StoryStatus.AwaitingReTestbyQA:
                case StoryStatus.AwaitingReTestbyCustomer:
                    mingleInQAX = currentMingleXyAllowed[0];
                    mingleInQAY = currentMingleXyAllowed[1];
                    break;
                case StoryStatus.ReadyForRegressionTesting:
                case StoryStatus.InRegressionTesting:
                case StoryStatus.ReadyForSAT:
                case StoryStatus.InSAT:
                    mingleShowCaseCompleteX = currentMingleXyAllowed[0];
                    mingleShowCaseCompleteY = currentMingleXyAllowed[1];
                    break;
                case StoryStatus.Closed:
                case StoryStatus.Deleted:
                case StoryStatus.Quarantine:
                    mingleClosedX = currentMingleXyAllowed[0];
                    mingleClosedY = currentMingleXyAllowed[1];
                    break;
            }
            
        }

        private List<double> GetCurrentXYAllowedForThisStatus(ProjectCardModel projectCardModel)
        {
            switch (projectCardModel.DevStage)
            {
                case StoryStatus.New:
                case StoryStatus.Triage:
                case StoryStatus.InPlanning:
                case StoryStatus.ReadyForAnalysis:
                case StoryStatus.InAnalysis:
                case StoryStatus.ReadyForDev:
                case StoryStatus.OnHold:
                case StoryStatus.Split:
                    return new List<double> {mingleReadyForDevX, mingleReadyForDevY, 300};
                case StoryStatus.InDev:
                case StoryStatus.InDevWaitingforBuild:
                case StoryStatus.ReadyForBAAcceptance:
                    return new List<double> {mingleInDevX, mingleInDevY, 850};
                case StoryStatus.ReadyForQA:
                case StoryStatus.InQA:
                case StoryStatus.ReadyForShowcase:
                case StoryStatus.ReadyForVerification:
                case StoryStatus.AwaitingFix:
                case StoryStatus.AwaitingReTestbyQA:
                case StoryStatus.AwaitingReTestbyCustomer:
                    return new List<double> { mingleInQAX, mingleInQAY, 1400};
                case StoryStatus.ReadyForRegressionTesting:
                case StoryStatus.InRegressionTesting:
                case StoryStatus.ReadyForSAT:
                case StoryStatus.InSAT:
                    return new List<double> { mingleShowCaseCompleteX, mingleShowCaseCompleteY, 2100};
                case StoryStatus.Closed:
                case StoryStatus.Deleted:
                case StoryStatus.Quarantine:
                    return new List<double> { mingleClosedX, mingleClosedY, 2650 };
            }
            return new List<double> { 0, 0, 0};
        }

        void ModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if(IsValidProperty(e.PropertyName))
                OnPropertyChanged(e.PropertyName);

            if(e.PropertyName == "Settings")
                OnPropertyChanged("DaysToIterationEnd");
        }

        public bool IsWallEmpty
        {
            get { return _model.IsWallEmpty; }
            set
            {
                if (_model.IsWallEmpty == value)
                    return;
                _model.IsWallEmpty = value;
                OnPropertyChanged("IsWallEmpty");
            }
        }

        void TeamMembers_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                var teamMemberModel = (TeamMemberModel)e.NewItems[0];
                var photoUri = teamMemberModel.PhotoUri == string.Empty
                                   ? "/PairingMatrix;component/View/Photo/Default.jpg"
                                   : teamMemberModel.PhotoUri;
                TeamMembers.Add(new TeamMemberCardViewModel(teamMemberModel));
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                var teamMemberModel = (TeamMemberModel)e.OldItems[0];
                TeamMembers.Remove(TeamMembers.First(c => c.Id == teamMemberModel.Id));
            }

        }

        void EndDateStrip_DateSelected(object sender, Common.Event.DateStripEventHandlerArgs args)
        {
            CurrentInstanceDate = args.Date;
        }

        public DateTime CurrentInstanceDate
        {
            get { return _model.CurrentInstanceDate; }
            set
            {
                if (_model.CurrentInstanceDate == value)
                    return;
                _model.CurrentInstanceDate = value;
                OnPropertyChanged("CurrentInstanceDate");
            }
        }

        void ProjectCards_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                var projectCardModel = (ProjectCardModel)e.NewItems[0];
                var projectCardViewModel = new ProjectCardViewModel(projectCardModel);
                ProjectCards.Add(projectCardViewModel);
            }
            else if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                ProjectCards.Clear();
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                var projectCardModel = (ProjectCardModel)e.OldItems[0];
                ProjectCards.Remove(ProjectCards.First(c => c.CardNumber == projectCardModel.CardNumber));
            }
        }

        public Point GetDefaultPositionAsPerDevelopmentStage(StoryStatus devStage)
        {
            double lowestCard = 30;
            const int HEIGHT_OF_CARD = 110;
            const int VERTICAL_DISTANCE_BETWEEN_CARDS = 100;
            return GetDefaultPositionAsPerDevelopmentStage(devStage, lowestCard + HEIGHT_OF_CARD + VERTICAL_DISTANCE_BETWEEN_CARDS);
        }

        public Point GetDefaultPositionAsPerDevelopmentStage(StoryStatus devStage, double y)
        {
            const int WIDTH_OF_DEV_STAGE = 360;
            const int WIDTH_OF_CARD = 200;

            const int POSITION_OF_READY_FOR_DEV_STAGE = 0;
            const int POSITION_OF_IN_DEV_STAGE = 1;
            const int POSITION_OF_IN_QA_STAGE = 2;
            const int POSITION_OF_SHOWCASE_DONE_STAGE = 3;
            const int POSITION_OF_CLOSED_STAGE = 4;

            IEnumerable<IProjectCardViewModel> cardsInDevStage;


            switch (devStage)
            {
                    
                
                case StoryStatus.New: 
                case StoryStatus.Triage: 
                case StoryStatus.InPlanning: 
                case StoryStatus.ReadyForAnalysis: 
                case StoryStatus.InAnalysis: 
                case StoryStatus.ReadyForDev: 
                case StoryStatus.OnHold: 
                case StoryStatus.Split: 
                    return new Point(WIDTH_OF_DEV_STAGE * POSITION_OF_READY_FOR_DEV_STAGE + (WIDTH_OF_DEV_STAGE * 0.5 - WIDTH_OF_CARD * 0.5), y);
                
                case StoryStatus.InDev: 
                case StoryStatus.InDevWaitingforBuild: 
                case StoryStatus.ReadyForBAAcceptance: 
                    return new Point(WIDTH_OF_DEV_STAGE * POSITION_OF_IN_DEV_STAGE + (WIDTH_OF_DEV_STAGE * 0.5 - WIDTH_OF_CARD * 0.5), y);
                
                case StoryStatus.ReadyForQA: 
                case StoryStatus.InQA: 
                case StoryStatus.ReadyForShowcase:
                case StoryStatus.ReadyForVerification: 
                case StoryStatus.AwaitingFix: 
                case StoryStatus.AwaitingReTestbyQA: 
                case StoryStatus.AwaitingReTestbyCustomer: 
                    return new Point(WIDTH_OF_DEV_STAGE * POSITION_OF_IN_QA_STAGE + (WIDTH_OF_DEV_STAGE*0.5 - WIDTH_OF_CARD*0.5), y);

                case StoryStatus.ReadyForRegressionTesting: 
                case StoryStatus.InRegressionTesting: 
                case StoryStatus.ReadyForSAT: 
                case StoryStatus.InSAT: 
                    return new Point(WIDTH_OF_DEV_STAGE * POSITION_OF_SHOWCASE_DONE_STAGE + (WIDTH_OF_DEV_STAGE*0.5 - WIDTH_OF_CARD*0.5), y);

                case StoryStatus.Closed: 
                case StoryStatus.Deleted:
                case StoryStatus.Quarantine:
                    return new Point(WIDTH_OF_DEV_STAGE * POSITION_OF_CLOSED_STAGE + (WIDTH_OF_DEV_STAGE * 0.5 - WIDTH_OF_CARD * 0.5), y);
 

            }
            return new Point(20, 100);
        }

        public ObservableCollection<ITeamMemberCardViewModel> TeamMembers { get; set; }
        public ObservableCollection<IProjectCardViewModel> ProjectCards { get; set; }
        public ObservableCollection<IProjectCardViewModel> MingleCards { get; set; }

        private RelayCommand _addProjectCardCommand;
        public RelayCommand AddProjectCardCommand
        {
            get {
                return _addProjectCardCommand ?? (_addProjectCardCommand = new RelayCommand(param => _model.AddProjectCard(((string)param) == "" ? 0 : Convert.ToInt32(param) )));
            }
        }


        private RelayCommand _newTeamMemberCommand;
        public RelayCommand NewTeamMemberCommand
        {
            get {
                return _newTeamMemberCommand ??
                       (_newTeamMemberCommand = new RelayCommand(param => _model.AddTeamMemberCard()));
            }
        }

        private RelayCommand _showPairingMatrixCommand;
        public RelayCommand ShowPairingMatrixCommand
        {
            get {
                return _showPairingMatrixCommand ??
                       (_showPairingMatrixCommand = new RelayCommand(param => ShowPairingMatrix = !ShowPairingMatrix));
            }
        }

        private bool _showPairingMatrix;
        public bool ShowPairingMatrix
        {
            get { return _showPairingMatrix; }
            set
            {
                if (_showPairingMatrix == value)
                    return;
                _showPairingMatrix = value;
                ShowCardWall = ! _showPairingMatrix;
                if(value == true)
                    SetUpDataForPairingMatrix();
                TeamMembers.ToList().ForEach(t => t.ArrangeCardToShowStatistics = _showPairingMatrix);
                ProjectCards.ToList().ForEach(c => c.ShowCard = !_showPairingMatrix);
                EndDateStrip.Show = !_showPairingMatrix;
                OnPropertyChanged("ShowPairingMatrix");
            }
        }

        private RelayCommand _showIceCreamMeterCommand;
        public RelayCommand ShowIceCreamMeterCommand
        {
            get {
                return _showIceCreamMeterCommand ??
                       (_showIceCreamMeterCommand = new RelayCommand(param => ShowIceCreamMeter = !ShowIceCreamMeter));
            }
        }


        private bool _showIceCreamMeter;
        public bool ShowIceCreamMeter
        {
            get { return _showIceCreamMeter; }
            set
            {
                if (_showIceCreamMeter == value)
                    return;
                _showIceCreamMeter = value;
                ShowCardWall = !_showIceCreamMeter;
                TeamMembers.ToList().ForEach(t => t.ArrangeCardToShowIceCreamMeter = _showIceCreamMeter);
                ProjectCards.ToList().ForEach(c => c.ShowCard = !_showIceCreamMeter);
                EndDateStrip.Show = !_showIceCreamMeter;
                OnPropertyChanged("ShowIceCreamMeter");
            }
        }

        private RelayCommand _showSettingsCommand;
        public RelayCommand ShowSettingsCommand
        {
            get {
                return _showSettingsCommand ??
                       (_showSettingsCommand = new RelayCommand(param => ShowSettings = !ShowSettings));
            }
        }




        private bool _showSettings;
        public bool ShowSettings
        {
            get { return _showSettings; }
            set
            {
                if (_showSettings == value)
                    return;
                _showSettings = value;
                ShowCardWall = !_showSettings;
                EndDateStrip.Show = !_showSettings;
                if (value == false)
                    SettingsViewModel.SaveCommand.Execute(null);
                OnPropertyChanged("ShowSettings");
            }
        }

        private RelayCommand _syncWithMingleCommand;
        public RelayCommand SyncWithMingleCommand
        {
            get {
                return _syncWithMingleCommand ??
                       (_syncWithMingleCommand = new RelayCommand(param => _model.SyncCardsFromMingle()));
            }
        }

        private RelayCommand _saveCommand;
        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand ??
                       (_saveCommand = new RelayCommand(param => _model.SaveData()));
            }
        }

        public bool IsSyncingAllProjectCards
        {
            get { return _model.IsSyncingAllProjectCards; }
            set
            {
                if (_model.IsSyncingAllProjectCards == value)
                    return;
                _model.IsSyncingAllProjectCards = value;
                OnPropertyChanged("IsSyncingAllProjectCards");
            }
        }


        private void SetUpDataForPairingMatrix()
        {
            _model.SetUpPairingData();
        }

        private bool _showCardWall = true;
        public bool ShowCardWall
        {
            get { return _showCardWall; }
            set
            {
                if (_showCardWall == value)
                    return;
                _showCardWall = value;
                OnPropertyChanged("ShowCardWall");
            }
        }

        private IDateStripViewModel _endDateStrip;
        public IDateStripViewModel EndDateStrip
        {
            get { return _endDateStrip; }
            set
            {
                if (_endDateStrip == value)
                    return;
                _endDateStrip = value;
                OnPropertyChanged("EndDateStrip");
            }
        }

        private IDateStripViewModel _startDateStrip;
        public IDateStripViewModel StartDateStrip
        {
            get { return _startDateStrip; }
            set
            {
                if (_startDateStrip == value)
                    return;
                _startDateStrip = value;
                OnPropertyChanged("StartDateStrip");
            }
        }

        private StoryStatus selectedStoryStatus = StoryStatus.New;
        public StoryStatus SelectedStoryStatus
        {
            get { return selectedStoryStatus; }
            set
            {
                if (selectedStoryStatus == value)
                    return;
                selectedStoryStatus = value;
                OnPropertyChanged("SelectedStoryStatus");
            }
        }

        public void AttachTeamMemberToProjectCard(ITeamMemberCardViewModel teamMemberCard, IProjectCardViewModel nearestProjectCard)
        {
            _model.AttachTeamMemberToProjectCard(teamMemberCard.Model, nearestProjectCard.Model);
        }

        public void DetachTeamMemberFromAllProjectCards(ITeamMemberCardViewModel teamMemberCard)
        {
            _model.DetachTeamMemberFromAllProjectCards(teamMemberCard.Model);
        }

        public void RemoveProjectCardFromWall(DateTime date, int cardNumber)
        {
            _model.RemoveProjectCardFromWall(date, cardNumber);
        }

        public void DeleteTeamMemberCard(Guid id)
        {
            _model.DeleteTeamMemberCard(id);
        }

        public void AttachSecondaryProjectCardToProjectCard(IProjectCardViewModel secondaryCard, IProjectCardViewModel primaryCard, double projectCardX, double projectCardY)
        {
            _model.AttachSecondaryProjectCardToProjectCard(secondaryCard.Model, primaryCard.Model, projectCardX, projectCardY);
        }

        public void DetachProjectCardFromAllProjectCards(IProjectCardViewModel projectCard)
        {
            _model.DetachProjectCardFromAllProjectCards(projectCard.Model);
        }

        private ITimer _timerViewModel;
        public ITimer TimerViewModel
        {
            get { return _timerViewModel; }
            set
            {
                if (_timerViewModel == value)
                    return;
                _timerViewModel = value;
                OnPropertyChanged("TimerViewModel");
            }
        }

        public string DaysToIterationEnd
        {
            get { return "Iteration ends in " + (DateTime.Parse(SettingsViewModel.IterationEndDate).Subtract(DateTime.Now).Days + 1) + " days"; }
        }

        private double _totalCostOfIceCreams; 
        public double TotalCostOfIceCreams 
        {
            get { return _totalCostOfIceCreams; }
            set
            {
                if (_totalCostOfIceCreams == value)
                    return;
                _totalCostOfIceCreams = value;
                var totalCountOfIceCreams = TeamMembers.Sum(t => t.IceCreams.Count);
                TeamMembers.ToList().ForEach(t => t.CalculateIceCreamCost(value, totalCountOfIceCreams));
                OnPropertyChanged("TotalCostOfIceCreams");
                OnPropertyChanged("IceCreamsDefaulterList");
            }
        }

        public string IceCreamsDefaulterList 
        {
            get
            {
                return string.Join(Environment.NewLine, TeamMembers.Select(t => t.Name + " - " + t.IceCreamCost + "/-"));
            }
        }


        private IPriorityCounterViewModel _readyForDevPriorityCounter;
        public IPriorityCounterViewModel ReadyForDevPriorityCounter
        {
            get { return _readyForDevPriorityCounter; }
            set
            {
                if (_readyForDevPriorityCounter == value)
                    return;
                _readyForDevPriorityCounter = value;
                OnPropertyChanged("ReadyForDevPriorityCounter");
            }
        }


        private IPriorityCounterViewModel _inDevPriorityCounter;
        public IPriorityCounterViewModel InDevPriorityCounter
        {
            get { return _inDevPriorityCounter; }
            set
            {
                if (_inDevPriorityCounter == value)
                    return;
                _inDevPriorityCounter = value;
                OnPropertyChanged("InDevPriorityCounter");
            }
        }


        private IPriorityCounterViewModel _inQAPriorityCounter;
        public IPriorityCounterViewModel InQAPriorityCounter
        {
            get { return _inQAPriorityCounter; }
            set
            {
                if (_inQAPriorityCounter == value)
                    return;
                _inQAPriorityCounter = value;
                OnPropertyChanged("InQAPriorityCounter");
            }
        }


        private IPriorityCounterViewModel _showcaseDonePriorityCounter;
        public IPriorityCounterViewModel ShowcaseDonePriorityCounter
        {
            get { return _showcaseDonePriorityCounter; }
            set
            {
                if (_showcaseDonePriorityCounter == value)
                    return;
                _showcaseDonePriorityCounter = value;
                OnPropertyChanged("ShowcaseDonePriorityCounter");
            }
        }


        private IPriorityCounterViewModel _closedPriorityCounter;
        public IPriorityCounterViewModel ClosedPriorityCounter
        {
            get { return _closedPriorityCounter; }
            set
            {
                if (_closedPriorityCounter == value)
                    return;
                _closedPriorityCounter = value;
                OnPropertyChanged("ClosedPriorityCounter");
            }
        }

        public AbsenteesViewModel AbsenteesViewModel
        {
            get { return absenteesViewModel; }
        }

        private RelayCommand _copyWallCommand;
        public RelayCommand CopyWallCommand
        {
            get {
                return _copyWallCommand ??
                       (_copyWallCommand = new RelayCommand(param => _model.CopyWallFromPreviousDay()));
            }
        }

        private RelayCommand _cancelCopyWallCommand;
        public RelayCommand CancelCopyWallCommand
        {
            get {
                return _cancelCopyWallCommand ??
                       (_cancelCopyWallCommand = new RelayCommand(param => IsWallEmpty = false));
            }
        }

        private RelayCommand _showStoryWallCommand;
        public RelayCommand ShowStoryWallCommand
        {
            get {
                return _showStoryWallCommand ??
                       (_showStoryWallCommand = new RelayCommand(param => _model.GetStoryWallCards()));
            }
        }

        private RelayCommand _showRegressionWallCommand;
        public RelayCommand ShowRegressionWallCommand
        {
            get {
                return _showRegressionWallCommand ??
                       (_showRegressionWallCommand = new RelayCommand(param => _model.GetRegressionWallCards()));

            }
        }

        private RelayCommand _showDpsWallCommand;
        public RelayCommand ShowDpsWallCommand
        {
            get {
                return _showDpsWallCommand ??
                       (_showDpsWallCommand = new RelayCommand(param => _model.GetDPSWallCards()));
            }
        }

        private ISettingsViewModel _settingsViewModel;
        public ISettingsViewModel SettingsViewModel
        {
            get { return _settingsViewModel; }
            set
            {
                if (_settingsViewModel == value)
                    return;
                _settingsViewModel = value;
                OnPropertyChanged("SettingsViewModel");
            }
        }

        private ToolBarViewModel _toolBarViewModel;
        public ToolBarViewModel ToolBarViewModel
        {
            get { return _toolBarViewModel ?? (_toolBarViewModel = new ToolBarViewModel(this)); }
        }


        private RelayCommand _clearIceCreamsCommand;
        public RelayCommand ClearIceCreamsCommand
        {
            get
            {
                return _clearIceCreamsCommand ?? (_clearIceCreamsCommand = new RelayCommand(param => TeamMembers.ToList().ForEach(t => t.ClearIceCreams())));
            }
        }

    }
}
